package com.pkche.core.advanced.safety;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * 配置文件监听器
 * 
 * @author admin
 * 
 */
public abstract class AllocationListener {

	// 文件路径
	private URL fileURL;
	// 上一次的刷新时间
	private long lastReload;

	// 判断是否为原始文件
	private boolean isPristineFile = true;

	/**
	 * 构建一个配置文件监听器
	 * 
	 * @param url
	 *            配置文件路径
	 * @param defaultRecord
	 *            默认的记录
	 */
	public AllocationListener(URL url, String defaultRecord) {
		fileURL = url;
		verifyJar();
		List<String> collect = getCollection();
		if ((defaultRecord != null) && (collect.size() < 1) && (isPristineFile)) {
			// 写入配置
			writerDefaultRecord(defaultRecord);
			// 读取配置并载入
			load(getCollection());
		} else {
			// 载入配置
			load(collect);
		}
	}

	// 验证是否为jar包
	private void verifyJar() {
		File file = null;
		try {
			file = new File(fileURL.toURI());
		} catch (IllegalArgumentException e) {
			isPristineFile = false;
		} catch (URISyntaxException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if (file != null) {
			lastReload = file.lastModified();
		}
	}

	/**
	 * 写入默认值
	 * 
	 * @param defaultRecord
	 */
	private void writerDefaultRecord(String defaultRecord) {
		File file = null;
		try {
			file = new File(fileURL.toURI());
		} catch (URISyntaxException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		BufferedWriter write = null;
		try {
			write = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream(file), "UTF-8"));
			// 将行写入到文件
			write.write(defaultRecord);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				write.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			// 设置时间
			lastReload = file.lastModified();
		}
	}

	/**
	 * 构建一个配置文件监听器
	 * 
	 * @param url
	 *            配置文件路径
	 */
	public AllocationListener(URL url) {
		this(url, null);
	}

	/**
	 * 刷新配置
	 * 
	 * @param list
	 *            配置文件中的记录行集合，忽略#号开头的配置
	 */
	public abstract void reload(List<String> list);

	/**
	 * 载入配置
	 * 
	 * @param list
	 */
	public abstract void load(List<String> list);

	/**
	 * 返回配置文件URL
	 */
	URL getURL() {
		return fileURL;
	}

	/**
	 * 返回文件路径
	 * 
	 * @return
	 */
	InputStream getInputStream() {
		try {
			return fileURL.openStream();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 设置最后载入时间
	 * 
	 * @param time
	 */
	void setLastReload(long time) {
		this.lastReload = time;
	}

	/**
	 * 获取最后载入配置时间
	 * 
	 * @return
	 */
	long getLastReload() {
		return this.lastReload;
	}

	/**
	 * 获取当前配置信息
	 * 
	 * @return
	 */
	protected List<String> getCollection() {
		BufferedReader in = null;
		List<String> list = new ArrayList<String>();
		try {
			in = new BufferedReader(new InputStreamReader(getInputStream(),
					"UTF-8"));
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			while (in.ready()) {
				String str = in.readLine();
				if ((str.startsWith("#")) || ("".equals(str))) {
					continue;
				}
				// System.out.println("**\t" + str);
				list.add(str);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return list;
	}

	/**
	 * 返回最后修改时间
	 * 
	 * @return
	 */
	public long lastModified() {
		if (!isPristineFile) {
			return 0;
		}
		try {
			return new File(fileURL.toURI()).lastModified();
		} catch (URISyntaxException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return 0;
	}
}
